package com.jyy.prefabricated.service;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jyy.prefabricated.dto.ExamApplyDto;
import com.jyy.prefabricated.dto.OrderDto;
import com.jyy.prefabricated.dto.OrderListDto;
import com.jyy.prefabricated.dto.XeOrderDto;
import com.jyy.prefabricated.entity.*;
import com.jyy.prefabricated.enums.*;
import com.jyy.prefabricated.exception.CustomException;
import com.jyy.prefabricated.mapper.*;
import com.jyy.prefabricated.utils.DateUtils;
import com.jyy.prefabricated.utils.KeyUtil;
import com.jyy.prefabricated.utils.UserUtils;
import com.jyy.prefabricated.utils.XiaoeClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @version 1.0.0
 * @author: zjj
 */
@Service
@Transactional
public class OrderInfoService {

    @Resource
    private UserUtils userUtils;

    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private StudentMapper studentMapper;

    @Resource
    private TrainingOrganizationService trainingOrganizationService;

    @Resource
    private TrainingOrganizationStockMapper trainingOrganizationStockMapper;

    @Resource
    private OrderInfoMapper orderInfoMapper;

    @Resource
    private CourseMapper courseMapper;

    @Resource
    private CourseCategoryMapper courseCategoryMapper;

    @Resource
    private CoursePackageMapper coursePackageMapper;

    @Resource
    private ProjectInfoMapper projectInfoMapper;

    @Resource
    private ProjectCategoryMapper projectCategoryMapper;

    @Resource
    private StudentCourseMapper studentCourseMapper;

    @Resource
    private StudentCoursePackageMapper studentCoursePackageMapper;

    @Resource
    private StudentProjectMapper studentProjectMapper;

    @Autowired
    private CompanyAdService companyAdService;

    @Resource
    private ExamPaperMapper paperMapper;

    @Resource
    private ContentCategoryMapper contentCategoryDao;

    @Resource
    private StudentExerciseMapper studentExerciseMapper;
    @Resource
    private StudentExerciseService studentExerciseService;

    @Resource
    private ExamMapper examMapper;

    @Resource
    private CoursePackageService coursePackageService;

    @Resource
    private ExamApplyMapper examApplyMapper;

    @Resource
    private ExamApplyStudentMapper applyStudentMapper;

    @Resource
    private TrainingOrganizationMapper trainingOrganizationMapper;


    @Resource
    private QuestionBankMapper questionBankMapper;

    /**
     * 创建订单
     *
     * @param orderDto
     * @return
     */
    public OrderInfo createOrder(OrderDto orderDto) {
        SysUser user = userUtils.getCurrentUser();
        if (UserTypeEnum.ADMIN.getValue().equals(user.getUserType())) {
            throw new CustomException("当前用户为系统管理员，无法购买商品！");
        } else if (UserTypeEnum.TRAININGORGANIZATION.getValue().equals(user.getUserType())) {
            //机构需要检验内容是否可以购买
//            checkOrder(orderDto, user);

        } else if (!UserTypeEnum.TRAININGORGANIZATION.getValue().equals(user.getUserType()) && orderDto.getOrderType().equals(OrderTypeEnum.QuestionBank.getValue())) {
            throw new CustomException("当前用户无法购买商品！");

        }
        OrderInfo orderInfo = new OrderInfo();
        String orderCode = KeyUtil.genUniqueKey();
        orderInfo.setBuyerId(user.getId());
        orderInfo.setOpenid(user.getOpenid());
        orderInfo.setBuyerName(user.getName());
        orderInfo.setOrderCode(orderCode);
        orderInfo.setPayStatus(PayStatusEnum.WAIT.getCode());
        orderInfo.setOrderStatus(OrderStatusEnum.NEW.getCode());
        orderInfo.setProductId(orderDto.getProductId());
        orderInfo.setQuantity(orderDto.getQuantity());
        orderInfo.setOrderType(orderDto.getOrderType());
        orderInfo.setBuyType(orderDto.getBuyType());
        orderInfo.setBuyTypeNum(orderDto.getBuyTypeNum());
        BigDecimal totalPrice = new BigDecimal("0");
        String productCategory = "";
        if (OrderTypeEnum.COURSE.getValue().equals(orderDto.getOrderType())) {
            Course product = courseMapper.selectByPrimaryKey(orderDto.getProductId());
            totalPrice = product.getPrice().multiply(new BigDecimal(orderDto.getQuantity().toString()));
            orderInfo.setPrice(product.getPrice());
            orderInfo.setProductName(product.getCourseName());
            orderInfo.setProductImage(product.getPic());
            if (product.getPic() == null) {
                orderInfo.setProductImage("");
            }
            orderInfo.setClassHours(product.getClassHours());
            orderInfo.setDistributionNum(product.getDistributionNum());
            List<CourseCategory> categories = courseCategoryMapper.selectAll();
            CourseCategory category = findParentCourseCategory(categories, product.getCategoryId());
            productCategory = category.getCategory();
        } else if (OrderTypeEnum.COURSE_PACKAGE.getValue().equals(orderDto.getOrderType())) {
            CoursePackage product = coursePackageMapper.selectByPrimaryKey(orderDto.getProductId());
            BigDecimal allPrice = new BigDecimal("0");
            if (orderDto.getBuyType() == 0) {
                allPrice = product.getPrice().multiply(new BigDecimal(orderDto.getBuyTypeNum().toString()));
            } else if (orderDto.getBuyType() == 1) {
                allPrice = product.getMonthPrice().multiply(new BigDecimal(orderDto.getBuyTypeNum().toString()));
            } else if (orderDto.getBuyType() == 2) {
                allPrice = product.getWeekPrice().multiply(new BigDecimal(orderDto.getBuyTypeNum().toString()));
            } else if (orderDto.getBuyType() == 3) {
                allPrice = product.getDayPrice().multiply(new BigDecimal(orderDto.getBuyTypeNum().toString()));
            }
            totalPrice = allPrice.multiply(new BigDecimal(orderDto.getQuantity().toString()));

            orderInfo.setPrice(product.getPrice());
            orderInfo.setProductName(product.getCourseName());
            orderInfo.setProductImage(product.getPic());
            orderInfo.setClassHours(product.getClassHours());
            orderInfo.setDistributionNum(product.getDistributionNum());
            List<CourseCategory> categories = courseCategoryMapper.selectAll();
            CourseCategory category = findParentCourseCategory(categories, product.getCategoryId());
            productCategory = category.getCategory();
        } else if (OrderTypeEnum.PROJECT.getValue().equals(orderDto.getOrderType())) {

            ProjectInfo product = projectInfoMapper.selectByPrimaryKey(orderDto.getProductId());
            if (UserTypeEnum.TRAININGORGANIZATION.getValue().equals(user.getUserType())) {
                TrainingOrganization trainingOrganization = trainingOrganizationService.selectByAccount(user.getUsername());
                //判断库存
                TrainingOrganizationStock trainingOrganizationStock = trainingOrganizationStockMapper.selectByTrainingOrganizationIdProductIdAndType(trainingOrganization.getId(), orderDto.getProductId(), orderDto.getOrderType());
                if (trainingOrganizationStock == null) {
                    //说明之前没有购买过该项目
                    if (product.getStock() != null) {
                        if (product.getStock() == 0) {
                            throw new CustomException("当前商品库存不足！");
                        } else {
                            product.setStock(product.getStock() - 1);
                            projectInfoMapper.updateByPrimaryKeySelective(product);
                        }
                    }
                } else {
                    //之前购买过，判断是否过期
                    if (product.getPosition() != null) {
                        List<CompanyAd> companyAds = companyAdService.selectByTo(trainingOrganization.getId(), product.getPosition(), BaseStatusEnum.VALID.getValue());
                        if (companyAds.size() == 0) {
                            //已经过期了
                            if (product.getStock() != null) {
                                if (product.getStock() == 0) {
                                    throw new CustomException("当前商品库存不足！");
                                } else {
                                    product.setStock(product.getStock() - 1);
                                    projectInfoMapper.updateByPrimaryKeySelective(product);
                                }
                            }
                        }
                    }
                }
            }
            totalPrice = product.getPrice().multiply(new BigDecimal(orderDto.getQuantity().toString()));
            orderInfo.setPrice(product.getPrice());
            orderInfo.setProductName(product.getName());
            orderInfo.setProductImage(product.getPic());
            List<ProjectCategory> categories = projectCategoryMapper.selectAll();
            ProjectCategory category = findParentProjectCategory(categories, product.getCategoryId());
            productCategory = category.getCategory();
        } else if (OrderTypeEnum.Practice.getValue().equals(orderDto.getOrderType())) {

            ExamPaper examPaper = paperMapper.selectByPrimaryKey(orderDto.getProductId());
            if (examPaper.getPrice() == null) {
                examPaper.setPrice(0d);
            }
            totalPrice = new BigDecimal(examPaper.getPrice()).multiply(new BigDecimal(orderDto.getQuantity().toString()));
            orderInfo.setPrice(new BigDecimal(examPaper.getPrice()));
            orderInfo.setProductName(examPaper.getName());
            orderInfo.setProductImage(examPaper.getPic());
            orderInfo.setDistributionNum(examPaper.getDistributionNum());
            ContentCategory contentCategory = contentCategoryDao.queryById(examPaper.getExercisesId());
            productCategory = contentCategory.getCategory();

        } else if (OrderTypeEnum.Exam.getValue().equals(orderDto.getOrderType())) {

            Exam exam = examMapper.selectByPrimaryKey(orderDto.getProductId());
            if (exam.getPrice() == null) {
                exam.setPrice(totalPrice);
            }
            totalPrice = exam.getPrice().multiply(new BigDecimal(orderDto.getQuantity().toString()));
            orderInfo.setPrice(exam.getPrice());
            orderInfo.setProductName(exam.getName());
            orderInfo.setProductImage(exam.getPic());

            productCategory = "考试";
        } else if (OrderTypeEnum.QuestionBank.getValue().equals(orderDto.getOrderType())) {

            QuestionBank product = questionBankMapper.selectByPrimaryKey(orderDto.getProductId());
            totalPrice = product.getPrice().multiply(new BigDecimal(orderDto.getQuantity().toString()));
            orderInfo.setPrice(product.getPrice());
            orderInfo.setProductName(product.getName());
            orderInfo.setProductImage("");
            productCategory = product.getCategory();
        } else {
            throw new CustomException("订单类型无法识别");
        }
        orderInfo.setProductCategory(productCategory);
        orderInfo.setTotalPrice(totalPrice);
        BigDecimal zero = new BigDecimal("0");
        if (totalPrice.compareTo(zero) == 0) {
            orderInfo.setPayStatus(PayStatusEnum.SUCCESS.getCode());

            orderInfo.setPayTime(DateUtils.formatDateTime(new Date()));
        }
        int orderId = insert(orderInfo);
        //免费的直接分配库存(题库不用分配库存)
        orderInfo.setId(orderId);
        if (totalPrice.compareTo(zero) == 0) {
            if (orderInfo.getOrderType().equals(OrderTypeEnum.QuestionBank.getValue())) {
                return selectById(orderId);
            }
            if (UserTypeEnum.TRAININGORGANIZATION.getValue().equals(user.getUserType())) {
                TrainingOrganization trainingOrganization = trainingOrganizationService.selectByAccount(user.getUsername());
                putStock(orderInfo, trainingOrganization);
            } else if (UserTypeEnum.STUDENT.getValue().equals(user.getUserType())) {
                Student student = studentMapper.selectByTel(user.getUsername());
                putStudentCourse(orderInfo, student);
            }
        }
        return selectById(orderId);
    }

    /**
     * 管理员创建订单
     *
     * @param dto
     * @return
     */
    public OrderInfo adminCreateOrder(OrderListDto dto) {
        if (dto != null && dto.getOrderDtoList().size() > 0) {
            for (OrderDto orderDto : dto.getOrderDtoList()) {
                TrainingOrganization tro = trainingOrganizationMapper.selectByPrimaryKey(dto.getTrainingOrganizationId());
                OrderInfo orderInfo = new OrderInfo();
                String orderCode = KeyUtil.genUniqueKey();
                orderInfo.setBuyerId(tro.getId());
                // orderInfo.setOpenid();
                orderInfo.setBuyerName(tro.getName());
                orderInfo.setOrderCode(orderCode);
                orderInfo.setPayStatus(PayStatusEnum.SUCCESS.getCode());
                orderInfo.setOrderStatus(OrderStatusEnum.NEW.getCode());
                orderInfo.setProductId(orderDto.getProductId());
                orderInfo.setQuantity(orderDto.getQuantity());
                orderInfo.setOrderType(dto.getOrderType());
                orderInfo.setBuyType(orderDto.getBuyType());
                orderInfo.setBuyTypeNum(orderDto.getBuyTypeNum());
                orderInfo.setPayType(orderDto.getPayType());
                orderInfo.setPayTime(orderDto.getPayTime());
                String productCategory = "";
                if (OrderTypeEnum.COURSE.getValue().equals(dto.getOrderType())) {
                    Course product = courseMapper.selectByPrimaryKey(orderDto.getProductId());

                    orderInfo.setPrice(product.getPrice());
                    orderInfo.setProductName(product.getCourseName());
                    orderInfo.setProductImage(product.getPic());
                    orderInfo.setClassHours(product.getClassHours());
                    orderInfo.setDistributionNum(product.getDistributionNum());
                    List<CourseCategory> categories = courseCategoryMapper.selectAll();
                    CourseCategory category = findParentCourseCategory(categories, product.getCategoryId());
                    productCategory = category.getCategory();
                } else if (OrderTypeEnum.COURSE_PACKAGE.getValue().equals(dto.getOrderType())) {
                    CoursePackage product = coursePackageMapper.selectByPrimaryKey(orderDto.getProductId());
                    orderInfo.setPrice(product.getPrice());
                    orderInfo.setProductName(product.getCourseName());
                    orderInfo.setProductImage(product.getPic());
                    orderInfo.setClassHours(product.getClassHours());
                    orderInfo.setDistributionNum(product.getDistributionNum());
                    List<CourseCategory> categories = courseCategoryMapper.selectAll();
                    CourseCategory category = findParentCourseCategory(categories, product.getCategoryId());
                    productCategory = category.getCategory();
                } else if (OrderTypeEnum.PROJECT.getValue().equals(dto.getOrderType())) {

                    ProjectInfo product = projectInfoMapper.selectByPrimaryKey(orderDto.getProductId());
                    TrainingOrganization trainingOrganization = trainingOrganizationService.selectByAccount(tro.getAccount());
                    //判断库存
                    TrainingOrganizationStock trainingOrganizationStock = trainingOrganizationStockMapper.selectByTrainingOrganizationIdProductIdAndType(trainingOrganization.getId(), orderDto.getProductId(), orderDto.getOrderType());
                    if (trainingOrganizationStock == null) {
                        //说明之前没有购买过该项目
                        if (product.getStock() != null) {
                            if (product.getStock() == 0) {
                                throw new CustomException("当前商品库存不足！");
                            } else {
                                product.setStock(product.getStock() - 1);
                                projectInfoMapper.updateByPrimaryKeySelective(product);
                            }
                        }
                    } else {
                        //之前购买过，判断是否过期
                        if (product.getPosition() != null) {
                            List<CompanyAd> companyAds = companyAdService.selectByTo(trainingOrganization.getId(), product.getPosition(), BaseStatusEnum.VALID.getValue());
                            if (companyAds.size() == 0) {
                                //已经过期了
                                if (product.getStock() != null) {
                                    if (product.getStock() == 0) {
                                        throw new CustomException("当前商品库存不足！");
                                    } else {
                                        product.setStock(product.getStock() - 1);
                                        projectInfoMapper.updateByPrimaryKeySelective(product);
                                    }
                                }
                            }
                        }

                    }
                    orderInfo.setPrice(product.getPrice());
                    orderInfo.setProductName(product.getName());
                    orderInfo.setProductImage(product.getPic());
                    List<ProjectCategory> categories = projectCategoryMapper.selectAll();
                    ProjectCategory category = findParentProjectCategory(categories, product.getCategoryId());
                    productCategory = category.getCategory();
                } else if (OrderTypeEnum.Practice.getValue().equals(dto.getOrderType())) {

                    ExamPaper examPaper = paperMapper.selectByPrimaryKey(orderDto.getProductId());
                    orderInfo.setPrice(new BigDecimal(examPaper.getPrice()));
                    orderInfo.setProductName(examPaper.getName());
                    orderInfo.setProductImage(examPaper.getPic());
                    orderInfo.setDistributionNum(examPaper.getDistributionNum());
                    ContentCategory contentCategory = contentCategoryDao.queryById(examPaper.getExercisesId());
                    productCategory = contentCategory.getCategory();

                } else if (OrderTypeEnum.Exam.getValue().equals(dto.getOrderType())) {

                    Exam exam = examMapper.selectByPrimaryKey(orderDto.getProductId());
                    orderInfo.setPrice(exam.getPrice());
                    orderInfo.setProductName(exam.getName());
                    orderInfo.setProductImage(exam.getPic());

                    productCategory = "考试";
                } else {
                    throw new CustomException("订单类型无法识别");
                }
                orderInfo.setProductCategory(productCategory);
                orderInfo.setTotalPrice(orderDto.getTotalPrice());
                orderInfo.setPayStatus(PayStatusEnum.SUCCESS.getCode());
              if(orderDto.getPayTime()!=null){
                  orderInfo.setPayTime(orderDto.getPayTime());
              }else{
                  orderInfo.setPayTime(DateUtils.formatDateTime(new Date()));
              }
              int orderId = insert(orderInfo);
                //直接分配库存
                orderInfo.setId(orderId);

                TrainingOrganization trainingOrganization = trainingOrganizationService.selectByAccount(tro.getAccount());
                putStock(orderInfo, trainingOrganization);
            }
        }
        return null;
    }

    /**
     * 创建订单(对公转账订单)
     *
     * @param orderDto
     * @return
     */
    public OrderInfo createPublicTransferOrder(OrderDto orderDto) {
        SysUser user = userUtils.getCurrentUser();
        if (UserTypeEnum.ADMIN.getValue().equals(user.getUserType())) {
            throw new CustomException("当前用户为系统管理员，无法购买商品！");
        } else if (UserTypeEnum.TRAININGORGANIZATION.getValue().equals(user.getUserType())) {
            //机构需要检验内容是否可以购买
//            checkOrder(orderDto, user);

        }
        OrderInfo orderInfo = new OrderInfo();
        String orderCode = KeyUtil.genUniqueKey();
        orderInfo.setBuyerId(user.getId());
        orderInfo.setOpenid(user.getOpenid());
        orderInfo.setBuyerName(user.getName());
        orderInfo.setOrderCode(orderCode);
         orderInfo.setPayStatus(PayStatusEnum.WAIT.getCode());
        orderInfo.setOrderStatus(OrderStatusEnum.Three.getCode());
        orderInfo.setProductId(orderDto.getProductId());
        orderInfo.setQuantity(orderDto.getQuantity());
        orderInfo.setOrderType(orderDto.getOrderType());
        orderInfo.setBuyType(orderDto.getBuyType());
        orderInfo.setBuyTypeNum(orderDto.getBuyTypeNum());
        orderInfo.setPayTime(orderDto.getPayTime());
        BigDecimal totalPrice = new BigDecimal("0");
        String productCategory = "";
        if (OrderTypeEnum.COURSE.getValue().equals(orderDto.getOrderType())) {
            Course product = courseMapper.selectByPrimaryKey(orderDto.getProductId());
            totalPrice = product.getPrice().multiply(new BigDecimal(orderDto.getQuantity().toString()));
            orderInfo.setPrice(product.getPrice());
            orderInfo.setProductName(product.getCourseName());
            orderInfo.setProductImage(product.getPic());
            orderInfo.setClassHours(product.getClassHours());
            List<CourseCategory> categories = courseCategoryMapper.selectAll();
            CourseCategory category = findParentCourseCategory(categories, product.getCategoryId());
            productCategory = category.getCategory();
        } else if (OrderTypeEnum.COURSE_PACKAGE.getValue().equals(orderDto.getOrderType())) {
            CoursePackage product = coursePackageMapper.selectByPrimaryKey(orderDto.getProductId());
            totalPrice = product.getPrice().multiply(new BigDecimal(orderDto.getQuantity().toString()));
            orderInfo.setPrice(product.getPrice());
            orderInfo.setProductName(product.getCourseName());
            orderInfo.setProductImage(product.getPic());
            orderInfo.setClassHours(product.getClassHours());
            List<CourseCategory> categories = courseCategoryMapper.selectAll();
            CourseCategory category = findParentCourseCategory(categories, product.getCategoryId());
            productCategory = category.getCategory();
        } else if (OrderTypeEnum.PROJECT.getValue().equals(orderDto.getOrderType())) {

            ProjectInfo product = projectInfoMapper.selectByPrimaryKey(orderDto.getProductId());
            if (UserTypeEnum.TRAININGORGANIZATION.getValue().equals(user.getUserType())) {
                TrainingOrganization trainingOrganization = trainingOrganizationService.selectByAccount(user.getUsername());
                //判断库存
                TrainingOrganizationStock trainingOrganizationStock = trainingOrganizationStockMapper.selectByTrainingOrganizationIdProductIdAndType(trainingOrganization.getId(), orderDto.getProductId(), orderDto.getOrderType());
                if (trainingOrganizationStock == null) {
                    //说明之前没有购买过该项目
                    if (product.getStock() != null) {
                        if (product.getStock() == 0) {
                            throw new CustomException("当前商品库存不足！");
                        } else {
                            product.setStock(product.getStock() - 1);
                            projectInfoMapper.updateByPrimaryKeySelective(product);
                        }
                    }
                } else {
                    //之前购买过，判断是否过期
                    if (product.getPosition() != null) {
                        List<CompanyAd> companyAds = companyAdService.selectByTo(trainingOrganization.getId(), product.getPosition(), BaseStatusEnum.VALID.getValue());
                        if (companyAds.size() == 0) {
                            //已经过期了
                            if (product.getStock() != null) {
                                if (product.getStock() == 0) {
                                    throw new CustomException("当前商品库存不足！");
                                } else {
                                    product.setStock(product.getStock() - 1);
                                    projectInfoMapper.updateByPrimaryKeySelective(product);
                                }
                            }
                        }
                    }
                }
            }
            totalPrice = product.getPrice().multiply(new BigDecimal(orderDto.getQuantity().toString()));
            orderInfo.setPrice(product.getPrice());
            orderInfo.setProductName(product.getName());
            orderInfo.setProductImage(product.getPic());
            List<ProjectCategory> categories = projectCategoryMapper.selectAll();
            ProjectCategory category = findParentProjectCategory(categories, product.getCategoryId());
            productCategory = category.getCategory();
        } else {
            throw new CustomException("订单类型无法识别");
        }
        orderInfo.setProductCategory(productCategory);
        orderInfo.setTotalPrice(totalPrice);
        orderInfo.setPayOrder(orderDto.getPayOrder());
        int orderId = insert(orderInfo);
        return selectById(orderId);
    }

    /**
     * 检验订单数据
     *
     * @param dto
     * @param user
     */
    public void checkOrder(OrderDto dto, SysUser user) {
        TrainingOrganization trainingOrganization = trainingOrganizationService.selectByAccount(user.getUsername());
        if (trainingOrganization == null) {
            throw new CustomException("无法识别当前机构！");
        }
        if (OrderTypeEnum.PROJECT.getValue().equals(dto.getOrderType())) {
            //判断商品时项目时是否可以购买
            if (trainingOrganization.getCanBuyProjects().stream().filter(e -> e.getId().equals(dto.getProductId())).count() == 0) {
                throw new CustomException("当前商品不可购买，请联系平台方！");
            }
        } else if (OrderTypeEnum.COURSE_PACKAGE.getValue().equals(dto.getOrderType())) {
            //判断商品是课程包是否可以购买
            if (trainingOrganization.getCanBuyCoursePackages().stream().filter(e -> e.getId().equals(dto.getProductId())).count() == 0) {
                throw new CustomException("当前商品不可购买，请联系平台方！");
            }
        } else if (OrderTypeEnum.COURSE.getValue().equals(dto.getOrderType())) {
            //判断商品是课程包是否可以购买
            List<Course> courses = trainingOrganization.getCanBuyCourses();
            for (CoursePackage coursePackage : trainingOrganization.getCanBuyCoursePackages()) {
                courses.addAll(coursePackage.getDocumentCourses());
                courses.addAll(coursePackage.getRecordingCourses());
            }
            if (courses.stream().filter(e -> e.getId() == dto.getProductId()).count() == 0) {
                throw new CustomException("当前商品不可购买，请联系平台方！");
            }
        }
    }

    /**
     * 递归查询课程主分类
     *
     * @param categories
     * @param categoryId
     * @return
     */
    private CourseCategory findParentCourseCategory(List<CourseCategory> categories, Integer categoryId) {
        CourseCategory category = categories.stream().filter(e -> e.getId().equals(categoryId)).findFirst().get();
        if (category.getPid() == null || category.getPid() == 0) {
            return category;
        }
        CourseCategory parentCategory = categories.stream().filter(
                x -> Objects.equals(x.getId(), category.getPid())
        ).findFirst().get();

        return findParentCourseCategory(categories, parentCategory.getId());
    }


    /**
     * 递归查询项目主分类
     *
     * @param categories
     * @param categoryId
     * @return
     */
    private ProjectCategory findParentProjectCategory(List<ProjectCategory> categories, Integer categoryId) {
        ProjectCategory category = categories.stream().filter(e -> e.getId().equals(categoryId)).findFirst().get();
        if (category.getPid() == null) {
            return category;
        }
        ProjectCategory parentCategory = categories.stream().filter(
                x -> Objects.equals(x.getId(), category.getPid())
        ).findFirst().get();

        return findParentProjectCategory(categories, parentCategory.getId());
    }

    /**
     * 新增
     *
     * @param orderInfo
     * @return
     */
    public Integer insert(OrderInfo orderInfo) {
        orderInfoMapper.insert(orderInfo);
        return orderInfo.getId();
    }

    /**
     * 修改
     *
     * @param orderInfo
     * @return
     */
    public int update(OrderInfo orderInfo) {
        if (orderInfo.getId() == null) {
            throw new CustomException("参数id不能为空");
        }
        return orderInfoMapper.updateByPrimaryKeySelective(orderInfo);
    }

    /**
     * 审核订单(对公转账订单)
     *
     * @param dto
     * @return
     */
    public int updateStatus(OrderInfo dto) {
        if (dto.getId() == null) {
            throw new CustomException("参数id不能为空");
        }
        if (OrderStatusEnum.FINISHED.getCode().equals(dto.getOrderStatus())) {
            OrderInfo orderInfo = orderInfoMapper.selectByOrderCode(dto.getOrderCode());
            orderInfo.setPayStatus(PayStatusEnum.SUCCESS.getCode());
            orderInfo.setOrderStatus(OrderStatusEnum.FINISHED.getCode());
            update(orderInfo);
            SysUser user = sysUserMapper.selectByPrimaryKey(orderInfo.getBuyerId());
            if (UserTypeEnum.STUDENT.getValue().equals(user.getUserType())) {
                //关联学生课程
                Student student = studentMapper.selectByTel(user.getUsername());
                putStudentCourse(orderInfo, student);
            } else if (UserTypeEnum.TRAININGORGANIZATION.getValue().equals(user.getUserType())) {
                //关联库存
                TrainingOrganization trainingOrganization = trainingOrganizationService.selectByAccount(user.getUsername());
                putStock(orderInfo, trainingOrganization);
                //新增广告位
                putCompanyAd(orderInfo, trainingOrganization);
            }
        } else if (OrderStatusEnum.Four.getCode().equals(dto.getOrderStatus())) {
            return orderInfoMapper.updateByPrimaryKeySelective(dto);
        }
        return 0;
    }

    /**
     * 支付成功后修改状态
     *
     * @param orderCode
     */
    public void paid(String orderCode) {
        OrderInfo orderInfo = orderInfoMapper.selectByOrderCode(orderCode);
        orderInfo.setPayStatus(PayStatusEnum.SUCCESS.getCode());
        orderInfo.setOrderStatus(OrderStatusEnum.FINISHED.getCode());
//        orderInfo.setExpireTime();
        update(orderInfo);
        if (orderInfo.getOrderType().equals(OrderTypeEnum.QuestionBank.getValue())) {
            return;
        }
        SysUser user = sysUserMapper.selectByPrimaryKey(orderInfo.getBuyerId());
        if (UserTypeEnum.STUDENT.getValue().equals(user.getUserType())) {
            //关联学生课程
            Student student = studentMapper.selectByTel(user.getUsername());
            putStudentCourse(orderInfo, student);
        } else if (UserTypeEnum.TRAININGORGANIZATION.getValue().equals(user.getUserType())) {
            //关联库存
            TrainingOrganization trainingOrganization = trainingOrganizationService.selectByAccount(user.getUsername());
            putStock(orderInfo, trainingOrganization);
            //新增广告位
            putCompanyAd(orderInfo, trainingOrganization);
        }
    }

    /**
     * 设置企业风采广告
     *
     * @param orderInfo
     * @param trainingOrganization
     */
    public void putCompanyAd(OrderInfo orderInfo, TrainingOrganization trainingOrganization) {
        if (orderInfo.getOrderType().equals(OrderTypeEnum.PROJECT.getValue())) {
            //如果当前订单类型为项目
            ProjectInfo projectInfo = projectInfoMapper.selectByPrimaryKey(orderInfo.getProductId());
            if (projectInfo.getPosition() != null) {
                //如果当前项目设置了广告位,先查找是否已经存在有效的广告位
                CompanyAd companyAd = null;
                List<CompanyAd> companyAds = companyAdService.selectByTo(trainingOrganization.getId(), projectInfo.getPosition(), BaseStatusEnum.VALID.getValue());
                if (companyAds.size() > 0) {
                    companyAd = companyAds.get(0);
                }
                //获取待生效的广告信息，如果待生效的信息存在，那么有效广告位一定不存在
                List<CompanyAd> waitStartAd = companyAdService.selectAdByWaitStart(trainingOrganization.getId(), projectInfo.getPosition());
                if (waitStartAd.size() > 0) {
                    //直接在待生效的广告信息上增加时间
                    companyAd = waitStartAd.get(0);
                }
                Calendar cal = Calendar.getInstance();
                if (companyAd != null) {
                    //存在广告位
                    cal.setTime(companyAd.getEndTime());
                } else {
                    //不存在广告位，需要新建
                    companyAd = new CompanyAd();
                    companyAd.setPosition(projectInfo.getPosition());
                    companyAd.setStartTime(new Date());
                    companyAd.setTrainingOrganizationId(trainingOrganization.getId());
                    if (trainingOrganization.getImage() != null && trainingOrganization.getContent() != null) {
                        companyAd.setImage(trainingOrganization.getImage());
                        companyAd.setContent(trainingOrganization.getContent());
                        companyAd.setStatus(BaseStatusEnum.VALID.getValue());
                    } else {
                        companyAd.setStatus(BaseStatusEnum.INVALID.getValue());
                    }

                    cal.setTime(companyAd.getStartTime());
                }
                if (projectInfo.getUnit() != null) {
                    if (projectInfo.getUnit().equals(TimeUnitEnum.DAY.getValue())) {
                        cal.add(Calendar.DATE, 1);
                    } else if (projectInfo.getUnit().equals(TimeUnitEnum.WEEK.getValue())) {
                        cal.add(Calendar.DATE, 7);
                    } else if (projectInfo.getUnit().equals(TimeUnitEnum.MONTH.getValue())) {
                        cal.add(Calendar.MONTH, 1);
                    } else if (projectInfo.getUnit().equals(TimeUnitEnum.YEAR.getValue())) {
                        cal.add(Calendar.YEAR, 1);
                    }
                    companyAd.setEndTime(cal.getTime());
                    if (companyAd.getId() != null) {
                        companyAdService.update(companyAd);
                    } else {
                        companyAdService.insert(companyAd);
                    }

                }
                if (!projectInfo.getPosition().equals(AdPositionEnum.COMPANY.getValue())) {
                    //给企业开通招聘权限
                    if (!trainingOrganization.getRecruit()) {
                        trainingOrganizationService.putRole(orderInfo.getBuyerId(), true);
                    }
                }
            }
        }
    }

    /**
     * 分配学员购买资源
     *
     * @param orderInfo
     * @param student
     */
    public void putStudentCourse(OrderInfo orderInfo, Student student) {
        if (OrderTypeEnum.COURSE.getValue().equals(orderInfo.getOrderType())) {
            //如果购买的商品为课程
            StudentCourse studentCourse = new StudentCourse();
            studentCourse.setCourseId(orderInfo.getProductId());
            studentCourse.setStudentId(student.getId());
            studentCourse.setType(RelationTypeEnum.BUY.getValue());
            studentCourseMapper.insert(studentCourse);
        } else if (OrderTypeEnum.COURSE_PACKAGE.getValue().equals(orderInfo.getOrderType())) {
            //如果购买的商品为课程包
            StudentCoursePackage studentCoursePackage = new StudentCoursePackage();
            studentCoursePackage.setPackageId(orderInfo.getProductId());
            studentCoursePackage.setStudentId(student.getId());
            studentCoursePackage.setType(RelationTypeEnum.BUY.getValue());
            studentCoursePackage.setOrderId(orderInfo.getId());
            studentCoursePackageMapper.insert(studentCoursePackage);
            //如果课程包下面包含考试和练习也分配

            //给学员分配考试和练习
            //查询该课程包下所包含的所有考试和练习，然后申请考试
            //分配考试
            CoursePackage coursePackage = coursePackageService.selectTree(orderInfo.getProductId());
            List<Exam> examList = coursePackageService.find(coursePackage);
            //去重
            examList = examList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Exam::getId))), ArrayList::new));

            if (examList != null && examList.size() > 0) {

                for (Exam exam : examList) {
                    ExamApply examApply = new ExamApply();
                    ExamApplyDto examApplyDto = new ExamApplyDto();

                    examApplyDto.setExamId(exam.getId());
                    List<Integer> studentIds = new ArrayList<>();
                    studentIds.add(student.getId());
                    examApplyDto.setStudentIds(studentIds);
                    BeanUtils.copyProperties(examApplyDto, examApply);
                    //审核通过
                    examApply.setStatus(ApplyStatusEnum.SUCCESS.getValue());

                    examApplyMapper.insert(examApply);
                    saveApplyId2Student(examApplyDto, examApply.getId());
                }
            }
            //分配练习
            List<ExamPaper> practicesList = coursePackageService.findPractices(coursePackage);
            if (practicesList != null && practicesList.size() > 0) {

                for (ExamPaper examPaper : practicesList) {
                    StudentExercise studentExercise = new StudentExercise();
                    studentExercise.setStudentId(student.getId());
                    studentExercise.setExerciseStatus(ExerciseStatusEnum.Four.getValue());
                    studentExercise.setExamPaperId(examPaper.getId());
                    studentExerciseMapper.insert(studentExercise);
                    Integer studentExerciseId = studentExercise.getId();

                    studentExerciseService.initExercisePaperDetailByExamPaperId(examPaper.getId(), studentExerciseId);
                }
            }

        } else if (OrderTypeEnum.PROJECT.getValue().equals(orderInfo.getOrderType())) {
            //如果购买的商品为项目
            StudentProject studentProject = new StudentProject();
            studentProject.setProjectId(orderInfo.getProductId());
            studentProject.setStudentId(student.getId());
            studentProject.setType(RelationTypeEnum.BUY.getValue());
            studentProjectMapper.insert(studentProject);
        } else if (OrderTypeEnum.Practice.getValue().equals(orderInfo.getOrderType())) {

            StudentExercise studentExercise = new StudentExercise();
            studentExercise.setStudentId(student.getId());
            studentExercise.setExerciseStatus(ExerciseStatusEnum.Four.getValue());
            studentExercise.setExamPaperId(orderInfo.getProductId());
            studentExerciseMapper.insert(studentExercise);
            Integer studentExerciseId = studentExercise.getId();

            studentExerciseService.initExercisePaperDetailByExamPaperId(orderInfo.getProductId(), studentExerciseId);
        }
    }


    /**
     * 分配机构库存
     *
     * @param orderInfo
     * @param trainingOrganization
     */
    public void putStock(OrderInfo orderInfo, TrainingOrganization trainingOrganization) {
        //课程包特殊处理、课程包有有效期
        if (OrderTypeEnum.COURSE_PACKAGE.getValue().equals(orderInfo.getOrderType())) {
//            TrainingOrganizationStock stock = trainingOrganizationStockMapper.selectCoursePackage(trainingOrganization.getId(), orderInfo.getProductId(), orderInfo.getOrderType(), orderInfo.getBuyType(), orderInfo.getBuyTypeNum());
            //设置可分配数量默认值，如果没设置则为1
            Integer num = orderInfo.getDistributionNum() != null ? orderInfo.getDistributionNum() : 1;
            //第一次购买，新建库存
            TrainingOrganizationStock newStock = new TrainingOrganizationStock();
            newStock.setTrainingOrganizationId(trainingOrganization.getId());
            newStock.setProductId(orderInfo.getProductId());
            newStock.setProductName(orderInfo.getProductName());
            newStock.setProductCategory(orderInfo.getProductCategory());

            CoursePackage coursePackage = coursePackageMapper.selectByPrimaryKey(orderInfo.getProductId());

            newStock.setInitNum(coursePackage.getDistributionNum() == null ? 1 : coursePackage.getDistributionNum());
            newStock.setCurrentNum(coursePackage.getDistributionNum() == null ? 1 : coursePackage.getDistributionNum());
            newStock.setClassHours(orderInfo.getClassHours());
            newStock.setType(orderInfo.getOrderType());
            newStock.setPrice(orderInfo.getPrice());
            newStock.setOrderId(orderInfo.getId());
            trainingOrganizationStockMapper.insert(newStock);

        } else {
            TrainingOrganizationStock stock = trainingOrganizationStockMapper.selectByTrainingOrganizationIdProductIdAndType(trainingOrganization.getId(), orderInfo.getProductId(), orderInfo.getOrderType());
            //设置可分配数量默认值，如果没设置则为1
            Integer num = orderInfo.getDistributionNum() != null ? orderInfo.getDistributionNum() : 1;
            if (stock == null) {
                //第一次购买，新建库存
                TrainingOrganizationStock newStock = new TrainingOrganizationStock();
                newStock.setTrainingOrganizationId(trainingOrganization.getId());
                newStock.setProductId(orderInfo.getProductId());
                newStock.setProductName(orderInfo.getProductName());
                newStock.setProductCategory(orderInfo.getProductCategory());
                newStock.setInitNum(orderInfo.getQuantity());
                newStock.setCurrentNum(orderInfo.getQuantity() * num);
                newStock.setClassHours(orderInfo.getClassHours());
                newStock.setType(orderInfo.getOrderType());
                newStock.setPrice(orderInfo.getPrice());
                newStock.setOrderId(orderInfo.getId());
                //资料文档购买一份后，可以无限分配
                if (OrderTypeEnum.COURSE.getValue().equals(orderInfo.getOrderType())) {
                    CourseWithBLOBs courseWithBLOBs = courseMapper.selectByPrimaryKey(orderInfo.getProductId());
                    if (courseWithBLOBs != null && courseWithBLOBs.getType().equals(CourseTypeEnum.DOCUMENT.getValue())) {
                        newStock.setInitNum(9999);
                        newStock.setCurrentNum(9999);
                    }
                }
                trainingOrganizationStockMapper.insert(newStock);
            } else {
                //在原有的基础上新增库存
                stock.setInitNum(stock.getInitNum() + orderInfo.getQuantity());
                stock.setCurrentNum(stock.getCurrentNum() + orderInfo.getQuantity() * num);
                trainingOrganizationStockMapper.updateByPrimaryKeySelective(stock);
            }

        }

    }

    /**
     * 删除
     *
     * @param id
     * @return
     */
    public int delete(Integer id) {
        return orderInfoMapper.deleteByPrimaryKey(id);
    }

    /**
     * 根据id查询
     *
     * @param id
     * @return
     */
    public OrderInfo selectById(Integer id) {
        OrderInfo orderInfo = orderInfoMapper.selectByPrimaryKey(id);
        if (OrderTypeEnum.COURSE.getValue().equals(orderInfo.getOrderType())) {
            CourseWithBLOBs course = courseMapper.selectByPrimaryKey(orderInfo.getProductId());
            orderInfo.setLecturer(course.getLecturer());
            orderInfo.setContent(course.getContent());
        } else if (OrderTypeEnum.COURSE_PACKAGE.getValue().equals(orderInfo.getOrderType())) {
            CoursePackage coursePackage = coursePackageMapper.selectByPrimaryKey(orderInfo.getProductId());
            orderInfo.setContent(coursePackage.getContent());
        } else if (OrderTypeEnum.Practice.getValue().equals(orderInfo.getOrderType())) {
            ExamPaper examPaper = paperMapper.selectByPrimaryKey(orderInfo.getProductId());
            orderInfo.setContent(examPaper.getContent());
        } else if (OrderTypeEnum.Exam.getValue().equals(orderInfo.getOrderType())) {
            Exam exam = examMapper.selectByPrimaryKey(orderInfo.getProductId());
            orderInfo.setContent(exam.getContent());
        } else {
            ProjectInfo projectInfo = projectInfoMapper.selectByPrimaryKey(orderInfo.getProductId());
            orderInfo.setContent(projectInfo.getContent());
        }

        return orderInfo;
    }

    /**
     * 根据订单号查询
     *
     * @param orderCode
     * @return
     */
    public OrderInfo selectByOrderCode(String orderCode) {
        return orderInfoMapper.selectByOrderCode(orderCode);
    }

    /**
     * 根据参数查询
     *
     * @param productName 产品名称
     * @param orderType   订单类型
     * @param orderStatus 订单状态
     * @param userId      用户id
     * @return
     */
    public List<OrderInfo> selectByParams(String productName, Integer orderType, Integer userId, Integer orderStatus, String startTime ,String endTime) {
        return orderInfoMapper.selectByParams(productName, orderType, userId, orderStatus ,startTime, endTime);
    }

    public void pullOrders() {
        String url = "https://api.xiaoe-tech.com/xe.order.list.get/1.0.1";
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) - 2);
        long beforeTwo = calendar.getTimeInMillis();
        String data = "{" +
                "  \"page_index\": \"1\"," +
                "  \"page_size\": \"50\"," +
                "  \"begin_time\": \"" + beforeTwo + "\"," +
                "  \"order_state\": \"1\"" +
                "}";
        XiaoeClient client = new XiaoeClient();
        Map result = client.request("post", url, data);
        System.out.println(result);
        Map map = (Map) result.get("data");
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        try {
            if (map != null && map.get("list") != null) {
                List<XeOrderDto> xeOrderDtos = mapper.readValue(map.get("list").toString(), new TypeReference<List<XeOrderDto>>() {
                });
                for (XeOrderDto xeOrderDto : xeOrderDtos) {
                    /**
                     * 查询是否是本平台用户订单
                     */
                    SysUser user = sysUserMapper.selectByUserId(xeOrderDto.getUser_id());
                    if (user != null) {
                        OrderInfo orderInfo = new OrderInfo();
                        String orderCode = KeyUtil.genUniqueKey();
                        orderInfo.setBuyerId(user.getId());
                        orderInfo.setBuyerName(user.getName());
                        orderInfo.setOrderCode(orderCode);
                        orderInfo.setPayStatus(PayStatusEnum.SUCCESS.getCode());
                        orderInfo.setOrderStatus(OrderStatusEnum.FINISHED.getCode());
                        orderInfo.setPayTime(xeOrderDto.getPay_time());
                        /**
                         * 查询商品
                         */
                        orderInfo.setQuantity(xeOrderDto.getCount());
                        String productCategory = "";
                        if (xeOrderDto.getResource_type().equals(3)) {
                            Course course = courseMapper.selectByResourceId(xeOrderDto.getResource_id());

                            orderInfo.setProductId(course.getId());
                            orderInfo.setOrderType(OrderTypeEnum.COURSE.getValue());
                            Course product = courseMapper.selectByPrimaryKey(course.getId());
                            orderInfo.setPrice(product.getPrice());
                            orderInfo.setProductName(product.getCourseName());
                            orderInfo.setProductImage(product.getPic());
                            orderInfo.setClassHours(product.getClassHours());
                            List<CourseCategory> categories = courseCategoryMapper.selectAll();
                            CourseCategory category = findParentCourseCategory(categories, product.getCategoryId());
                            productCategory = category.getCategory();
                        } else if (xeOrderDto.getResource_type().equals(6) || xeOrderDto.getResource_type().equals(8)) {

                            /*orderInfo.setOrderType(OrderTypeEnum.COURSE_PACKAGE.getValue());
                            CoursePackage product = coursePackageMapper.selectByPrimaryKey(orderDto.getProductId());
                            orderInfo.setPrice(product.getPrice());
                            orderInfo.setProductName(product.getCourseName());
                            orderInfo.setProductImage(product.getPic());
                            orderInfo.setClassHours(product.getClassHours());
                            List<CourseCategory> categories = courseCategoryMapper.selectAll();
                            CourseCategory category = findParentCourseCategory(categories,product.getCategoryId());
                            productCategory = category.getCategory();*/
                        }
                        orderInfo.setProductCategory(productCategory);
                        orderInfo.setTotalPrice(BigDecimal.valueOf(xeOrderDto.getPrice()));
                        OrderInfo order = new OrderInfo();
                        order.setBuyerId(orderInfo.getBuyerId());
                        order.setProductId(orderInfo.getProductId());
                        order.setPayTime(orderInfo.getPayTime());
                        List<OrderInfo> orderInfos = orderInfoMapper.selectOrders(order);
                        if (orderInfos != null && orderInfos.size() > 0) {

                        } else {
                            int orderId = insert(orderInfo);
                            if (UserTypeEnum.STUDENT.getValue().equals(user.getUserType())) {
                                //关联学生课程
                                Student student = studentMapper.selectByTel(user.getUsername());
                                putStudentCourse(orderInfo, student);
                            } else if (UserTypeEnum.TRAININGORGANIZATION.getValue().equals(user.getUserType())) {
                                //关联库存
                                TrainingOrganization trainingOrganization = trainingOrganizationService.selectByAccount(user.getUsername());
                                putStock(orderInfo, trainingOrganization);
                                //新增广告位
                                putCompanyAd(orderInfo, trainingOrganization);
                            }
                        }

                    }

                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 保存申请和学员的绑定信息
     *
     * @param dto
     * @param id
     */
    public void saveApplyId2Student(ExamApplyDto dto, Integer id) {
        if (dto.getStudentIds().size() > 0) {
            List<ExamApplyStudent> applyStudents = new ArrayList<>();
            for (Integer studentId : dto.getStudentIds()) {
                ExamApplyStudent applyStudent = new ExamApplyStudent();
                applyStudent.setApplyId(id);
                applyStudent.setStudentId(studentId);
                applyStudents.add(applyStudent);
            }
            applyStudentMapper.batchInsert(applyStudents);
        }
    }

}
